package streaming;

import simulation.ChunkStatusEnum;
import simulation.Message;

/**
 * Node overrequests packets
 */
public class Attacker2 extends Host {

	public Attacker2(int id) {
		super(id);
	}
	
	public void requestPacket() {
		
		periodicRequest.addEvent();
		
		if (neighborQueue.isEmpty()) {
			return;
		}

		int seqNo = -1;
		Neighbor neighbor = null;
		Host n = null;
		
		// Request every available packet from every neighbor with whom outstanding limit is not reached
		int length = neighborQueue.size();
		// for every neighbor
		for (int i = 0; i < length; i++) {
			neighbor = (Neighbor)neighbors.get(new Integer(((Host)neighborQueue.get(0)).id));
			n = (Host)neighborQueue.get(0);
			seqNo = neighbor.getRandomNotification();
			// while there are available packets
			while (seqNo != -1) {
				// Request packet
				new Message("request", this, n, seqNo, false);
				setPacketStatus(seqNo, ChunkStatusEnum.PENDING);
				auxCount ++;
				neighbor.addRequestedPacket(seqNo, simulator.getTime());
				//	ATTACK: Do not remove sequence number from list of notified packets of other neighbors
				neighbor.removeNotifiedPacket(seqNo);
				if (neighbor.hasNotified(seqNo))
					System.out.println("buggy buggy buggy");
				// Check if host's outstanding limit of requests has been reached. - n is of class Host (unlike neighbor)
				if (neighbor.outstanding >= StreamingConfig.MCASTMAXOUTSTANDING ) {
					neighborQueue.remove(n);
					outstandingNeighbors.add(n);
					break;
				}
				seqNo = neighbor.getRandomNotification();
			}
			// If there are no more elements to be fetched, just move neighbor to the end of the queue
			if (neighborQueue.contains(n)) {
				neighborQueue.remove(0);
				neighborQueue.add(n);
			}
			// In either case - the neighbor will be removed from the top of the queue
		}
	}	
	
	/**
	 * Almost same as in host - mainly copied for debugging purposes
	 */
	public void handlePacket(int seqNo, Host source) {
		
		if (!interestWindow.isWithin(seqNo))
			return;
		
		Neighbor neighbor = (Neighbor)neighbors.get(new Integer(source.id));
		if (!neighbor.removeRequestedPacket(seqNo))
			System.out.println("Problem with removing request packet in  handlePacket");
		
		if (outstandingNeighbors.contains(source)) {
			outstandingNeighbors.remove(source);		
			neighborQueue.add(source);
		}
		if (getPacketStatus(seqNo) == ChunkStatusEnum.PENDING)
			notifyNeighbors(seqNo);
		setPacketStatus(seqNo, ChunkStatusEnum.RECEIVED);
		receivedCount++;
	}
	
}